package com.santalu.emptyview;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.text.Font;
import ohos.agp.transition.Transition;
import ohos.agp.transition.TransitionAlpha;
import ohos.agp.transition.TransitionMove;
import ohos.agp.transition.TransitionZoomingMove;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by santalu on 09/08/2017.
 */

public class EmptyViewBuilder {
    public static final int NONE = 0;

    // Gravity
    public static final int TOP = 48;
    public static final int CENTER = 17;
    public static final int BOTTOM = 80;

    // Loading Type
    public static final int CIRCULAR = 1;

    // State
    public static final int CONTENT = 1;
    public static final int LOADING = 2;
    public static final int EMPTY = 3;
    public static final int ERROR = 4;

    // Transition
    public static final int SLIDE = 1;
    public static final int EXPLODE = 2;
    public static final int FADE = 3;
    public static final int AUTO = 4;
    List<Component> children;
    State state;
    int gravity;

    // Shared attributes
    int titleTextSize;
    int textSize;
    int buttonTextSize;
    Font font;
    Transition transition;
    Component.ClickedListener onClickListener;

    // Loading state attributes
    LoadingType loadingType;
    String loadingTitle;
    int loadingTitleTextColor;
    String loadingText;
    int loadingTextColor;
    Element loadingDrawable;
    int loadingDrawableTint;
    int loadingBackgroundColor;

    // Empty state attributes
    String emptyTitle;
    int emptyTitleTextColor;
    String emptyText;
    int emptyTextColor;
    String emptyButtonText;
    int emptyButtonTextColor;
    int emptyButtonBackgroundColor;
    Element emptyDrawable;
    int emptyDrawableTint;
    int emptyBackgroundColor;

    // Error state attributes
    String errorTitle;
    int errorTitleTextColor;
    String errorText;
    int errorTextColor;
    String errorButtonText;
    int errorButtonTextColor;
    int errorButtonBackgroundColor;
    Element errorDrawable;
    int errorDrawableTint;
    int errorBackgroundColor;

    private final EmptyView emptyView;
    private final Context context;

    private EmptyViewBuilder(EmptyView emptyView) {
        this.emptyView = emptyView;
        this.context = emptyView.getContext();
        this.children = new ArrayList<>();
    }

    EmptyViewBuilder(EmptyView emptyView, AttrSet attrSet) {
        this(emptyView);
        int defaultTextColor = Color.BLACK.getValue();
        gravity = AttrUtils.getInteger(attrSet, "ev_gravity", CENTER);
        if (attrSet.getAttr("ev_transition").isPresent()) {
            int type = AttrUtils.getInteger(attrSet, "ev_transition", NONE);
            TransitionType transitionType = TransitionType.NONE;
            switch (type) {
                case NONE:
                    transitionType = TransitionType.NONE;
                    break;
                case FADE:
                    transitionType = TransitionType.FADE;
                    break;
                case SLIDE:
                    transitionType = TransitionType.SLIDE;
                    break;
                case EXPLODE:
                    transitionType = TransitionType.EXPLODE;
                    break;
            }
            setTransition(transitionType);
        }
        getFont(attrSet);
        titleTextSize = AttrUtils.getInteger(attrSet, "ev_titleTextSize", 0);
        textSize = AttrUtils.getInteger(attrSet, "ev_textSize", 0);
        buttonTextSize = AttrUtils.getInteger(attrSet, "ev_buttonTextSize", 0);

        // Loading state attributes
        int type = AttrUtils.getInteger(attrSet, "ev_loading_type", CIRCULAR);
        LoadingType loadType = LoadingType.NONE;
        switch (type) {
            case NONE:
                loadType = LoadingType.NONE;
                break;
            case CIRCULAR:
                loadType = LoadingType.CIRCULAR;
        }
        loadingType = loadType;

        loadingTitle = AttrUtils.getString(attrSet, "ev_loading_title", "");

        loadingTitleTextColor = AttrUtils.getColor(attrSet, "ev_loading_titleTextColor", defaultTextColor);

        loadingText = AttrUtils.getString(attrSet, "ev_loading_text", "");

        loadingTextColor = AttrUtils.getColor(attrSet, "ev_loading_textColor", defaultTextColor);

        loadingDrawable = AttrUtils.getElement(attrSet, "ev_loading_drawable", null);

        loadingDrawableTint = AttrUtils.getInteger(attrSet, "ev_loading_drawableTint", 0);

        loadingBackgroundColor = AttrUtils.getColor(attrSet, "ev_loading_backgroundColor", 0);

        // Empty state attributes
        emptyTitle = AttrUtils.getString(attrSet, "ev_empty_title", "");

        emptyTitleTextColor = AttrUtils.getColor(attrSet, "ev_empty_titleTextColor",
                defaultTextColor);

        emptyText = AttrUtils.getString(attrSet, "ev_empty_text", "");

        emptyTextColor = AttrUtils.getColor(attrSet, "ev_empty_textColor", defaultTextColor);

        emptyButtonText = AttrUtils.getString(attrSet, "ev_empty_button", "");

        emptyButtonTextColor = AttrUtils.getColor(attrSet, "ev_empty_buttonTextColor",
                defaultTextColor);

        emptyButtonBackgroundColor = AttrUtils.getColor(attrSet, "ev_empty_buttonBackgroundColor",
                0);

        emptyDrawable = AttrUtils.getElement(attrSet, "ev_empty_drawable", null);

        emptyDrawableTint = AttrUtils.getColor(attrSet, "ev_empty_drawableTint", 0);

        emptyBackgroundColor = AttrUtils.getColor(attrSet, "ev_empty_backgroundColor", 0);

        // Error state attributes
        errorTitle = AttrUtils.getString(attrSet, "ev_error_title", "");

        errorTitleTextColor = AttrUtils.getColor(attrSet, "ev_error_titleTextColor",
                defaultTextColor);

        errorText = AttrUtils.getString(attrSet, "ev_error_text", "");

        errorTextColor = AttrUtils.getColor(attrSet, "ev_error_textColor", defaultTextColor);

        errorButtonText = AttrUtils.getString(attrSet, "ev_error_button", "");

        errorButtonTextColor = AttrUtils.getColor(attrSet, "ev_error_buttonTextColor",
                defaultTextColor);
        errorButtonBackgroundColor = AttrUtils.getColor(attrSet, "ev_error_buttonBackgroundColor",
                0);
        errorDrawable = AttrUtils.getElement(attrSet, "ev_error_drawable", null);

        errorDrawableTint = AttrUtils.getColor(attrSet, "ev_error_drawableTint", 0);

        errorBackgroundColor = AttrUtils.getColor(attrSet, "ev_error_backgroundColor", 0);
    }

    private void getFont(AttrSet attrSet) {
        String fontStr = AttrUtils.getString(attrSet, "ev_font", "DEFAULT");
        switch (fontStr) {
            case "DEFAULT":
                font = Font.DEFAULT;
                break;
            case "DEFAULT_BOLD":
                font = Font.DEFAULT_BOLD;
                break;
            case "MONOSPACE":
                font = Font.MONOSPACE;
                break;
            case "SANS_SERIF":
                font = Font.SANS_SERIF;
                break;
            case "SERIF":
                font = Font.SERIF;
                break;
        }
    }

    public EmptyViewBuilder setOnClickListener(Component.ClickedListener onClickListener) {
        this.onClickListener = onClickListener;
        return this;
    }

    public EmptyViewBuilder exclude(int... ids) {
        for (int id : ids) {
            Component view = emptyView.findComponentById(id);
            if (children.contains(view)) {
                children.remove(view);
            }
        }
        return this;
    }

    public EmptyViewBuilder exclude(Component... views) {
        for (Component view : views) {
            if (children.contains(view)) {
                children.remove(view);
            }
        }
        return this;
    }

    public EmptyViewBuilder include(int... ids) {
        for (int id : ids) {
            Component view = emptyView.findComponentById(id);
            if (!children.contains(view)) {
                children.add(view);
            }
        }
        return this;
    }

    public EmptyViewBuilder include(Component... views) {
        for (Component view : views) {
            if (!children.contains(view)) {
                children.add(view);
            }
        }
        return this;
    }

    public EmptyViewBuilder setTransition(TransitionType type) {
        switch (type) {
            case NONE:
            default:
                transition = null;
                break;
            case EXPLODE:
                transition = new TransitionZoomingMove();
                break;
            case FADE:
                transition = new TransitionAlpha();
                break;
            case SLIDE:
                transition = new TransitionMove();
                break;
        }
        return this;
    }

    public EmptyViewBuilder setState(State state) {
        this.state = state;
        return this;
    }

    public EmptyViewBuilder setLoadingType(LoadingType loadingType) {
        this.loadingType = loadingType;
        return this;
    }

    public EmptyViewBuilder setLoadingTitle(int id) {
        return setLoadingTitle(EmptyUtils.getString(context, id));
    }

    public EmptyViewBuilder setLoadingTitle(String loadingTitle) {
        this.loadingTitle = loadingTitle;
        return this;
    }

    public EmptyViewBuilder setLoadingText(int id) {
        return setLoadingText(EmptyUtils.getString(context, id));
    }

    public EmptyViewBuilder setLoadingText(String loadingText) {
        this.loadingText = loadingText;
        return this;
    }

    public EmptyViewBuilder setLoadingDrawable(int id) {
        return setLoadingDrawable(EmptyUtils.getDrawable(context, id));
    }

    public EmptyViewBuilder setLoadingDrawable(Element loadingDrawable) {
        this.loadingDrawable = loadingDrawable;
        return this;
    }

    public EmptyViewBuilder setEmptyTitle(int id) {
        return setEmptyTitle(EmptyUtils.getString(context, id));
    }

    public EmptyViewBuilder setEmptyTitle(String emptyTitle) {
        this.emptyTitle = emptyTitle;
        return this;
    }

    public EmptyViewBuilder setEmptyText(int id) {
        return setEmptyText(EmptyUtils.getString(context, id));
    }

    public EmptyViewBuilder setEmptyText(String emptyText) {
        this.emptyText = emptyText;
        return this;
    }

    public EmptyViewBuilder setEmptyButtonText(int id) {
        return setEmptyButtonText(EmptyUtils.getString(context, id));
    }

    public EmptyViewBuilder setEmptyButtonText(String emptyButtonText) {
        this.emptyButtonText = emptyButtonText;
        return this;
    }

    public EmptyViewBuilder setEmptyDrawable(int id) {
        return setEmptyDrawable(EmptyUtils.getDrawable(context, id));
    }

    public EmptyViewBuilder setEmptyDrawable(Element emptyDrawable) {
        this.emptyDrawable = emptyDrawable;
        return this;
    }

    public EmptyViewBuilder setErrorTitle(int id) {
        return setErrorTitle(EmptyUtils.getString(context, id));
    }

    public EmptyViewBuilder setErrorTitle(String errorTitle) {
        this.errorTitle = errorTitle;
        return this;
    }

    public EmptyViewBuilder setErrorText(int id) {
        return setErrorText(EmptyUtils.getString(context, id));
    }

    public EmptyViewBuilder setErrorText(String errorText) {
        this.errorText = errorText;
        return this;
    }

    public EmptyViewBuilder setErrorButtonText(int id) {
        return setErrorButtonText(EmptyUtils.getString(context, id));
    }

    public EmptyViewBuilder setErrorButtonText(String errorButtonText) {
        this.errorButtonText = errorButtonText;
        return this;
    }

    public EmptyViewBuilder setErrorDrawable(int id) {
        return setErrorDrawable(EmptyUtils.getDrawable(context, id));
    }

    public EmptyViewBuilder setErrorDrawable(Element errorDrawable) {
        this.errorDrawable = errorDrawable;
        return this;
    }

    public void show() {
        emptyView.show();
    }

    public enum TransitionType {
        NONE, SLIDE, EXPLODE, FADE, AUTO
    }

    public enum LoadingType {
        NONE,
        CIRCULAR;
    }

    public enum State {
        CONTENT, EMPTY, ERROR, LOADING
    }
}
